package com.fulu.game.bi.service.impl.cash;

import cn.hutool.core.date.DateUtil;
import com.fulu.game.bi.common.util.csv.CsvExportUtil;
import com.fulu.game.bi.common.util.csv.Mapper;
import com.fulu.game.bi.common.util.csv.Querier;
import com.fulu.game.bi.entity.bo.channel.CashConvertListBO;
import com.fulu.game.bi.entity.bo.channel.CashInvestListBO;
import com.fulu.game.bi.entity.bo.channel.CashRealTimeBO;
import com.fulu.game.bi.entity.bo.channel.CashRefundListBO;
import com.fulu.game.bi.entity.enums.PlatformCashEnum;
import com.fulu.game.bi.entity.enums.QueryTypeStatusEnum;
import com.fulu.game.bi.entity.enums.TypeEnum;
import com.fulu.game.bi.entity.vo.cash.CashConvertListVO;
import com.fulu.game.bi.entity.vo.cash.CashInvestListVO;
import com.fulu.game.bi.entity.vo.cash.CashRefundListVO;
import com.fulu.game.bi.entity.vo.cash.PlatformCashRealtimeVO;
import com.fulu.game.bi.hbase.HBaseCashStatDAO;
import com.fulu.game.bi.redis.service.cash.PlatformCashService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class PlatformCashServiceImpl implements PlatformCashService {
    @Autowired
    private HBaseCashStatDAO hBaseCashStatDAO;

    public static final Map<Integer, String> cashInvestStat = new HashMap();

    public static final Map<Integer, String> cashConvertStat = new HashMap();

    public static final Map<Integer, String> cashRefundStat = new HashMap();

    static {
        cashRefundStat.put(QueryTypeStatusEnum.DAY.getType(), "cash_refund_stat_day");
        cashRefundStat.put(QueryTypeStatusEnum.WEEK.getType(), "cash_refund_stat_week");
        cashRefundStat.put(QueryTypeStatusEnum.MONTH.getType(), "cash_refund_stat_month");
    }

    static {
        cashConvertStat.put(QueryTypeStatusEnum.DAY.getType(), "cash_convert_stat_day");
        cashConvertStat.put(QueryTypeStatusEnum.WEEK.getType(), "cash_convert_stat_week");
        cashConvertStat.put(QueryTypeStatusEnum.MONTH.getType(), "cash_convert_stat_month");
    }

    static {
        cashInvestStat.put(QueryTypeStatusEnum.DAY.getType(), "cash_invest_stat_day");
        cashInvestStat.put(QueryTypeStatusEnum.WEEK.getType(), "cash_invest_stat_week");
        cashInvestStat.put(QueryTypeStatusEnum.MONTH.getType(), "cash_invest_stat_month");
    }

    @Override
    public List<PlatformCashRealtimeVO> realTime(Integer type) {
        PlatformCashEnum.CashTypeEnum anEnum = PlatformCashEnum.CashTypeEnum.getByType(type);
        CashRealTimeBO cashRealTimeBO = new CashRealTimeBO();
        cashRealTimeBO.setTableName(anEnum.getTable());
        cashRealTimeBO.setStatDate(DateUtil.today());
        List<PlatformCashRealtimeVO> today = hBaseCashStatDAO.findByParameter(cashRealTimeBO);
        today = handleRealtimeVO(anEnum, today, true);
        cashRealTimeBO.setStatDate(DateUtil.formatDate(DateUtil.offsetDay(new Date(), -1)));
        List<PlatformCashRealtimeVO> yesterday = hBaseCashStatDAO.findByParameter(cashRealTimeBO);
        yesterday = handleRealtimeVO(anEnum, yesterday, false);
        List<PlatformCashRealtimeVO> list = new ArrayList<>();
        list.addAll(today);
        list.addAll(yesterday);
        return list;
    }

    @Override
    public List<CashInvestListVO> investList(CashInvestListBO cashInvestListBO) {
        cashInvestListBO.setTableName(cashInvestStat.get(cashInvestListBO.getQueryType()));
        List<CashInvestListVO> list = hBaseCashStatDAO.investList(cashInvestListBO);
        return list.stream().map(map -> {
            map.setChannel(map.getChannel() == null ? "/" : map.getChannel());
            map.setPayType(map.getPayType() == null ? "/" : map.getPayType());
            map.setQueryType(cashInvestListBO.getQueryType());
            return map;
        }).collect(Collectors.toList());
    }

    @Override
    public void investExport(CashInvestListBO bo) {
        String fileName = "平台资金-充值";
        LinkedHashMap<String, Mapper<CashInvestListVO>> map = new LinkedHashMap<>();
        QueryTypeStatusEnum anEnum = QueryTypeStatusEnum.getEnum(bo.getQueryType());
        switch (anEnum) {
            case DAY:
                map.put("日期", v -> v.getStartDate());
                break;
            default:
                map.put("日期", v -> v.getStartDate() + "-" + v.getEndDate());
                break;
        }
        map.put("充值渠道", v -> v.getChannel());
        map.put("支付方式", v -> v.getPayType());
        map.put("充值人数", v -> v.getUserNum() + "");
        map.put("充值次数", v -> v.getNum() + "");
        map.put("充值金额", v -> v.getMoney() + "");
        Querier querier = (num) -> {
            PageInfo pageInfo = new PageInfo(investList(bo));
            pageInfo.setHasNextPage(false);
            return pageInfo;
        };
        CsvExportUtil.export(100, fileName, map, querier);
    }

    @Override
    public List<CashConvertListVO> convertList(CashConvertListBO cashConvertListBO) {
        cashConvertListBO.setTableName(cashConvertStat.get(cashConvertListBO.getQueryType()));
        List<CashConvertListVO> list = hBaseCashStatDAO.convertList(cashConvertListBO);
        return list.stream().map(map -> {
            map.setCurrency(map.getCurrency() == null ? "/" : map.getCurrency());
            map.setType(map.getType() == null ? "/" : map.getType());
            map.setQueryType(cashConvertListBO.getQueryType());
            return map;
        }).collect(Collectors.toList());
    }

    @Override
    public void convertExport(CashConvertListBO bo) {
        String fileName = "平台资金-兑换";
        LinkedHashMap<String, Mapper<CashConvertListVO>> map = new LinkedHashMap<>();
        QueryTypeStatusEnum anEnum = QueryTypeStatusEnum.getEnum(bo.getQueryType());
        switch (anEnum) {
            case DAY:
                map.put("日期", v -> v.getStartDate());
                break;
            default:
                map.put("日期", v -> v.getStartDate() + "-" + v.getEndDate());
                break;
        }
        map.put("兑换货币", v -> v.getCurrency());
        map.put("兑换方式", v -> v.getType());
        map.put("兑换人数", v -> v.getUserNum() + "");
        map.put("兑换次数", v -> v.getNum() + "");
        map.put("兑换支出金额", v -> v.getOutMoney() + "");
        map.put("兑换收入金额", v -> v.getInMoney() + "");
        Querier querier = (num) -> {
            PageInfo pageInfo = new PageInfo(convertList(bo));
            pageInfo.setHasNextPage(false);
            return pageInfo;
        };
        CsvExportUtil.export(100, fileName, map, querier);
    }

    @Override
    public List<CashRefundListVO> refundList(CashRefundListBO cashRefundListBO) {
        cashRefundListBO.setTableName(cashRefundStat.get(cashRefundListBO.getQueryType()));
        List<CashRefundListVO> list = hBaseCashStatDAO.refundList(cashRefundListBO);
        return list.stream().map(map -> {
            map.setType(map.getType() == null ? "/" : map.getType());
            map.setQueryType(cashRefundListBO.getQueryType());
            return map;
        }).collect(Collectors.toList());
    }

    @Override
    public void refundExport(CashRefundListBO bo) {
        String fileName = "平台资金-退款";
        LinkedHashMap<String, Mapper<CashRefundListVO>> map = new LinkedHashMap<>();
        QueryTypeStatusEnum anEnum = QueryTypeStatusEnum.getEnum(bo.getQueryType());
        switch (anEnum) {
            case DAY:
                map.put("日期", v -> v.getStartDate());
                break;
            default:
                map.put("日期", v -> v.getStartDate() + "-" + v.getEndDate());
                break;
        }
        map.put("退款类型", v -> v.getType());
        map.put("退款人数", v -> v.getUserNum() + "");
        map.put("退款次数", v -> v.getNum() + "");
        map.put("退款金额", v -> v.getMoney() + "");
        Querier querier = (num) -> {
            PageInfo pageInfo = new PageInfo(refundList(bo));
            pageInfo.setHasNextPage(false);
            return pageInfo;
        };
        CsvExportUtil.export(100, fileName, map, querier);
    }


    private List<PlatformCashRealtimeVO> handleRealtimeVO(PlatformCashEnum.CashTypeEnum anEnum, List<PlatformCashRealtimeVO> vos, boolean isToday) {
        for (TypeEnum<Integer> e : anEnum.getTypeEnums()) {
            final boolean[] hasValue = {false};
            vos.forEach(map -> {
                if (Objects.equals(e.getType(), map.getType())) {
                    hasValue[0] = true;
                    map.setName(e.getMsg());
                    map.setIsToday(isToday);
                }
            });
            if (!hasValue[0]) {
                PlatformCashRealtimeVO platformCashRealtimeVO = new PlatformCashRealtimeVO();
                platformCashRealtimeVO.setName(e.getMsg());
                platformCashRealtimeVO.setType(e.getType());
                platformCashRealtimeVO.setUserNum(0);
                platformCashRealtimeVO.setNum(0);
                platformCashRealtimeVO.setMoney(BigDecimal.ZERO);
                platformCashRealtimeVO.setIsToday(isToday);
                vos.add(platformCashRealtimeVO);
            }
        }
        return vos;
    }

}
